﻿// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Interfaces/IHttpRequest.h"
#include "CoreMinimal.h"
#include "ProtocolSubsystem.generated.h"

UENUM(BlueprintType, Category = "Runtime Files Downloader")
enum DownloadResult
{
	SuccessDownloading UMETA(DisplayName = "Success"),
	DownloadFailed UMETA(DisplayName = "Download failed"),
	SaveFailed UMETA(DisplayName = "Save failed"),
	DirectoryCreationFailed UMETA(DisplayName = "Directory creation failed")};

DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnFilesDownloaderProgress, const int32, const int32, const int32);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnFilesDownloaderResult, TEnumAsByte <DownloadResult>);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnHTTPPostResult, FString);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnHTTPGetResult, FString);

UCLASS()
class MISCELLANEOUSPROJECT_API UProtocolSubsystem : public UGameInstanceSubsystem 
{
	GENERATED_BODY()
public:
	virtual bool ShouldCreateSubsystem(UObject* Outer) const override { return true; }
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;

public:
	bool DownloadFile(const FString& URL, const FString& SavePath);
	FOnFilesDownloaderProgress& OnFileDownloadProgress() { return OnProgress; }
	FOnFilesDownloaderResult& OnFileDownloadRead() { return OnResult; }

	bool HTTPPostMessage(const FString& URL, const FString& PostData);
	FOnHTTPPostResult& OnPostReady() { return OnPostResult; }

	bool HTTPGetMessage(const FString& URL);
	FOnHTTPGetResult& OnGetReady() { return OnGetResult; }
	
private:
	TSharedRef<IHttpRequest,ESPMode::ThreadSafe> HTTPRequest(const FString& URL, const FString& Verb, const FString& Header = TEXT("{\"Content-Type\", \"application/json;charset=UTF-8\"}"), const FString& Content = TEXT(""));

	FString FileURL;
	FString FileSavePath;
	FOnFilesDownloaderProgress OnProgress;
	FOnFilesDownloaderResult OnResult;
	void OnFileDownloadProgress(FHttpRequestPtr Request, int32 BytesSent, int32 BytesReceived);
	void OnFileDownloadReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);

	FOnHTTPPostResult OnPostResult;
	void OnPostReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);

	FOnHTTPGetResult OnGetResult;
	void OnGetReady(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
};
